package com.demo.security.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.util.Assert;

import com.demo.security.access.model.SecurityResource;
import com.demo.security.core.SecurityMetadataSourceResolver;
import com.demo.security.expression.SourceResolverHandler;

/**
 * 基于String类型的安全元数据资源处理类
 * 该类处理表达式和分解器类型，返回安全配置属性。
 * 
 * @author ryuu.kk
 *
 */
public class MethodSecurityMetadataSourceHandler implements SecurityMetadataSourceResolver {

	/** log日志 **/
	protected final Log logger = LogFactory.getLog(getClass());
	
	/**
	 * 表达式处理类
	 */
	private Map<String, SourceResolverHandler> resolverHandlerMap;
	
	/**
	 * 构造方法
	 */
	public MethodSecurityMetadataSourceHandler() {
		
		if (resolverHandlerMap == null) {
			resolverHandlerMap = new HashMap<String, SourceResolverHandler>() {
				
				/**
				 * 版本序列化ID
				 */
				private static final long serialVersionUID = 1L;
				{	
					// 基于Spring-EL表达式的解析器
					put(SecurityMetadataSourceResolver.METADATA_SPEL, new ExpressionSourceResolverHandler());
					// 基于Role角色的解析器
					put(SecurityMetadataSourceResolver.METADATA_ROLE, new ExpressionSourceResolverHandler());
				}
			};
		}
	}
	
	/**
	 * 构造方法
	 */
	public MethodSecurityMetadataSourceHandler(Map<String, SourceResolverHandler> resolverHandlerMap) {
		Assert.notNull(resolverHandlerMap);
		this.resolverHandlerMap = resolverHandlerMap;
	}
	
	@Override
	public Map<String, List<ConfigAttribute>> resolver(List<SecurityResource> methodRescs) {
		Assert.notEmpty(methodRescs);
		Map<String, List<ConfigAttribute>> mappedAttr = new HashMap<String, List<ConfigAttribute>>();
		
		for (SecurityResource resc : methodRescs) {
			
			Assert.notNull(resc.getResolver());
			
			SourceResolverHandler resolverHandler = resolverHandlerMap.get(resc.getResolver());
			List<ConfigAttribute> attrs = resolverHandler.createConfigAttribute(resc);
			
			// 站点资源
			String name = resc.getResource();
//			String name = resc.getResString();			
//			if (attrs == null || attrs.isEmpty()) {
//				continue;
//			}
//			if (resc.getMethod() != null && !"".equals(resc.getMethod())) {
//				name += "." + resc.getMethod();
//			}
//			//参数非空,拼接方法
//			if (!resc.getArgs().isEmpty()) {
//				name += "(" + resc.getArgs() + ")";
//			}
			if (mappedAttr.containsKey(name)) {
				if (logger.isDebugEnabled()) {
					logger.debug("method : " + name + " has existed.");
				}
				List<ConfigAttribute> attrTmp = mappedAttr.get(name);
				for (ConfigAttribute attr : attrs) {
					attrTmp.add(attr);
				}
			} else {
				mappedAttr.put(name, attrs);				
			}
		}
		return mappedAttr;
	}

	public void setResolverHandlerMap(Map<String, SourceResolverHandler> resolverHandlerMap) {
		this.resolverHandlerMap = resolverHandlerMap;
	}
}
